use std::rc::Rc;

use web_sys::wasm_bindgen::{closure::Closure, JsCast};

fn recursive_render<F: Fn(f64, f64) -> bool + 'static, E: Fn() + 'static>(
    render: Rc<F>,
    state: Rc<Vec<f64>>,
    end_callback: Rc<E>,
    frame_index: f64,
    last_index: f64,
) {
    if frame_index > last_index {
        return end_callback();
    }

    let current_state = state[frame_index as usize];
    {
        let end_callback = end_callback.clone();
        let render = render.clone();
        let closure = Closure::<dyn Fn()>::wrap(Box::new(move || {
            let next = render(current_state, frame_index);
            if !next {
                return end_callback();
            }
            let f = frame_index + 1.;

            recursive_render(
                render.clone(),
                state.clone(),
                end_callback.clone(),
                f,
                last_index,
            );
        }));
        let _ = web_sys::window()
            .unwrap()
            .request_animation_frame(closure.as_ref().unchecked_ref());
    }
}

pub async fn create_animator<F: Fn(f64, f64) -> bool + 'static, E: Fn() + 'static>(
    render: Rc<F>,
    state: Rc<Vec<f64>>,
    end_callback: Rc<E>,
    frame_index: f64,
    last_index: f64,
) {
    recursive_render(render, state, end_callback, frame_index, last_index);
}
